#include "../model/osdremoteservicemodel.h"
#include "../model/osdutilsmodel.h"
#include "../control/mainwindowcontroller.h"
#include "../control/msgpagecontroller.h"
#include "../control/pwdpagecontroller.h"
#include "../control/keyboardcontroller.h"
#include "../control/indexpagecontroller.h"
#include "indexpage.h"
#include "ui_indexpage.h"
#include <QVBoxLayout>
#include <QEvent>
#include <QKeyEvent>
#include <QLayoutItem>
#include <QObject>
#include <QDebug>
#include <QDateTime>
#include "scheduleitem.h"
#include "viewglobal.h"
#include "passwordinput.h"
#include "../osdglobal.h"
#include "../remoteservice/platfromstatusinfo.h"
#include "shadewidget.h"
#include "../remoteservice/remoteerr.h"
#include "../sys/sysconfighandler.h"
#include "indexpageworker.h"
#include <QRegExp>
#include <QRegExpValidator>
#include <QDateTime>

#define UPDATE_SCHRDULE_TIMEOUT (10*60*1000)
#define NO_SCHEDULE_PAGE    (0)
#define SCHEDULE_PAGE       (1)
#define UPDATE_PER_SECONDS  (60)
#define QRCODE_PATH         QString("/opt/local/web/qrcode.png")

bool compareAsc(const ScheduleInfo::schedule_t &value1, const ScheduleInfo::schedule_t &value2)
{
    return value1.start_time < value2.start_time;
}

IndexPage::IndexPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::IndexPage),
    m_contentWidget(NULL),
    hasShade(false),
    m_originalHeight(0),
    m_curposition(0),
    m_currentCount(0),
    m_seconds((12*60*60))
{
    ui->setupUi(this);
    m_confNum = "";
    ui->leConfNumber->setContextMenuPolicy(Qt::NoContextMenu);

    caculateDuration();

    qRegisterMetaType<LIST_SCHEDULES>("LIST_SCHEDULES");

    worker = new IndexPageWorker;

    connect(this, SIGNAL(updateSchedule()), worker, SLOT(work()));
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(checkUpdates()));
    m_timer.start(UPDATE_SCHRDULE_TIMEOUT);

    initFocusOrder();

    ui->widCall->installEventFilter(this);
    ui->widAdvancedSetting->installEventFilter(this);
    ui->widBaseSetting->installEventFilter(this);
    ui->leConfNumber->installEventFilter(this);
    ui->lineedit_widget->installEventFilter(this);

    ui->lblCall->setFocusProxy(ui->widCall);
    ui->widAdvancedSettingLogo->setFocusProxy(ui->widAdvancedSetting);
    ui->lblAdvancedSettingText->setFocusProxy(ui->widAdvancedSetting);

    QRegExp rx("[0-9]{0,15}");
    QRegExpValidator *validator = new QRegExpValidator(rx, this);
    ui->leConfNumber->setValidator(validator);

    m_shadeWidget = new ShadeWidget(ui->widSch);
    m_shadeWidget->hide();

    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyCall(BaseResp)),
            this, SLOT(callSlot(BaseResp)));
    connect(&OSDRemoteServiceModel::instance(),
            SIGNAL(notifyProductInfo(ProductInfo)),
            this, SLOT(productInfoSlot(ProductInfo)));

    connect(&OSDRemoteServiceModel::instance(), SIGNAL(notifyScheduleList(ScheduleInfo)), this, SLOT(receiveSchedule(ScheduleInfo)));
    connect(&IndexPageController::instance(), SIGNAL(resetUiSig()), this, SLOT(resetUi()));

#ifdef __linux
//显示二维码
ui->lblQRCode->setPixmap(QPixmap(QRCODE_PATH));
ui->lblQRCode->setScaledContents(true);
#endif

    connect(&m_calendar_timer, SIGNAL(timeout()), this, SLOT(timerHandle()));
    timerHandle();
    m_calendar_timer.start(1000);
}

IndexPage::~IndexPage()
{
    workThread.quit();
    workThread.wait();
    if (m_contentWidget) {delete m_contentWidget; m_contentWidget = NULL;}
    delete worker;
    delete ui;
}

void IndexPage::caculateDuration()
{
    m_today=QDateTime::currentDateTime();
    QDateTime secondday=m_today.addDays(1);
    secondday.setTime(QTime(0,0,0,0));
    m_seconds = secondday.toTime_t() - m_today.toTime_t();
    qDebug() << "today: " << m_today;
    qDebug() << "secondday: " << secondday;
    qDebug() << "duration(s): "<< m_seconds;
}

void IndexPage::checkUpdates()
{
    QDateTime curtime=QDateTime::currentDateTime();
    uint duration = curtime.toTime_t()-m_today.toTime_t();
    if (duration > m_seconds)
    {
        caculateDuration();
        emit updateSchedule();
    }
}

void IndexPage::resetUi()
{
    ui->leConfNumber->setText("");
}

void IndexPage::receiveSchedule(ScheduleInfo schedule)
{
    if (schedule.getIsSuccess())
    {
        refreshSchedule(schedule.getSchedules());
    }
    else
    {
        qDebug() << "parse schedule failed!";
    }
}

void IndexPage::productInfoSlot(ProductInfo info)
{
    if (info.getIsSuccess())
    {
        ui->lblSN->setText(info.getSn());
    }
}

void IndexPage::initFocusOrder()
{
    QList<QObject *> orderlist;
    orderlist.clear();
    orderlist<< NULL << ui->widgetScroll << NULL << ui->widCall;
    m_ctrlOrder.insert(ui->leConfNumber, orderlist);

    orderlist.clear();
    orderlist<< NULL << ui->widgetScroll << NULL << ui->widCall;
    m_ctrlOrder.insert(ui->lineedit_widget, orderlist);

    orderlist.clear();
    orderlist<< POINTER_FOCUS_PREV << POINTER_FOCUS_NEXT <<  NULL << ui->widBaseSetting;
    m_ctrlOrder.insert(ui->widgetScroll, orderlist);

    orderlist.clear();
    orderlist<< NULL << ui->widgetScroll <<  ui->lineedit_widget << ui->widBaseSetting;
    m_ctrlOrder.insert(ui->widCall, orderlist);

    orderlist.clear();
    orderlist<< ui->lineedit_widget << ui->widAdvancedSetting <<  ui->lineedit_widget << NULL;
    m_ctrlOrder.insert(ui->widBaseSetting, orderlist);

    orderlist.clear();
    orderlist<< ui->widBaseSetting << NULL <<  ui->lineedit_widget << NULL;
    m_ctrlOrder.insert(ui->widAdvancedSetting, orderlist);
}

bool IndexPage::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QEvent::MouseButtonRelease)
    {
        if (ui->widCall->hasFocus())
        {
            m_confNum = ui->leConfNumber->text();
            call(m_confNum,SysConfigHandler::instance().deviceName());
        }
        else if (ui->widAdvancedSetting->hasFocus())
        {
            MainWindowController::instance().changeSubPage(OSD::ViewGlobal::SUB_PAGE_ADVANCE_CONFIG);
        }
        else if (ui->widBaseSetting->hasFocus())
        {
            MainWindowController::instance().changeSubPage(OSD::ViewGlobal::SUB_PAGE_BASE_CONFIG);
        } else if (ui->lineedit_widget->hasFocus())
        {
            ui->leConfNumber->setFocus();
        }

        if (QString(o->metaObject()->className()) == QString("ScheduleItem"))
        {
            ScheduleItem* item = dynamic_cast<ScheduleItem*>(o);
            QDateTime cur = QDateTime::currentDateTime();
            QString curStr = cur.toString("yyyy-MM-dd h:mm");
            if (curStr < item->starttime())
            {
                QString tip = "日程未开始，请稍后尝试！";
                MsgPageController::instance().showMsg(tip);
            }
            else if (curStr > item->starttime() && curStr < item->endtime())
            {
                m_confNum = item->conferenceNumber();
                call(item->conferenceNumber(),SysConfigHandler::instance().deviceName());
            }
        }
    }
    else if (e->type() == QEvent::FocusIn)
    {
        if (o == ui->widAdvancedSetting)
        {
            ui->widAdvancedSetting->setProperty("selffocus","1");
            ui->widAdvancedSettingLogo->setProperty("selffocus","1");
            ui->lblAdvancedSettingText->setProperty("selffocus","1");

            ui->widAdvancedSetting->style()->unpolish(ui->widAdvancedSetting);
            ui->widAdvancedSetting->style()->polish(ui->widAdvancedSetting);

            ui->widAdvancedSettingLogo->style()->unpolish(ui->widAdvancedSettingLogo);
            ui->widAdvancedSettingLogo->style()->polish(ui->widAdvancedSettingLogo);

            ui->lblAdvancedSettingText->style()->unpolish(ui->lblAdvancedSettingText);
            ui->lblAdvancedSettingText->style()->polish(ui->lblAdvancedSettingText);
        }
        else if(o == ui->widBaseSetting)
        {
            ui->widBaseSetting->setProperty("selffocus","1");
            ui->widBaseSettingLogo->setProperty("selffocus","1");
            ui->lblBaseSettingText->setProperty("selffocus","1");

            ui->widBaseSetting->style()->unpolish(ui->widBaseSetting);
            ui->widBaseSetting->style()->polish(ui->widBaseSetting);

            ui->widBaseSettingLogo->style()->unpolish(ui->widBaseSettingLogo);
            ui->widBaseSettingLogo->style()->polish(ui->widBaseSettingLogo);

            ui->lblBaseSettingText->style()->unpolish(ui->lblBaseSettingText);
            ui->lblBaseSettingText->style()->polish(ui->lblBaseSettingText);
        }
        else if (o == ui->leConfNumber)
        {
//            KeyBoardController::instance().show(ui->leConfNumber,0);
            ui->lineedit_widget->setProperty("selffocus","1");
            ui->lineedit_widget->style()->unpolish(ui->lineedit_widget);
            ui->lineedit_widget->style()->polish(ui->lineedit_widget);
            ui->lineedit_widget->update();
            m_curposition = ui->leConfNumber->cursorPosition();
        } else if (o == ui->lineedit_widget)
        {
            ui->lineedit_widget->setProperty("selffocus","1");
            ui->lineedit_widget->style()->unpolish(ui->lineedit_widget);
            ui->lineedit_widget->style()->polish(ui->lineedit_widget);
        }

        if (QString(o->metaObject()->className()) == QString("ScheduleItem"))
        {
            qDebug() << "o:" << o;

            if (m_currentCount > 0)
            {
                currentItem = o;
                if(!hasShade)
                {
                    //显示遮罩
                    QRect rect = ui->widSchMain->rect();
                    rect.setY(rect.y() + 85);
                    rect.setHeight(rect.height() + 85);
                    m_shadeWidget->setGeometry(rect);
                    m_shadeWidget->show();
                    hasShade = true;
                }
                if(m_contentWidget)
                {
                    m_contentWidget->setMinimumHeight(m_originalHeight+140);
                    //根据index，计算ui->widgetScroll，y的位置
                    QWidget *w = dynamic_cast<QWidget *>(currentItem);
                    int index = m_contentWidget->layout()->indexOf(w);
                    m_contentWidget->setGeometry(m_contentWidget->x(),
                                                 index*(-140)+140-(20*(index)),
                                                 m_contentWidget->width(),
                                                 m_contentWidget->height());
                }
            }
        }
        else
        {
            currentItem = NULL;
            if (hasShade)
            {
                //关闭遮罩
                m_shadeWidget->hide();
                hasShade = false;
                if(m_contentWidget)
                {
                    m_contentWidget->setMaximumHeight(m_originalHeight);
                    m_contentWidget->setMinimumHeight(m_originalHeight);
                    m_contentWidget->setGeometry(0,0,ui->widgetScroll->width(), m_originalHeight);
                }
            }
        }
    }
    else if (e->type() == QEvent::FocusOut)
    {
        if (o == ui->widAdvancedSetting)
        {
            //去掉阴影
            ui->widAdvancedSetting->setProperty("selffocus","0");
            ui->widAdvancedSettingLogo->setProperty("selffocus","0");
            ui->lblAdvancedSettingText->setProperty("selffocus","0");

            ui->widAdvancedSetting->style()->unpolish(ui->widAdvancedSetting);
            ui->widAdvancedSetting->style()->polish(ui->widAdvancedSetting);

            ui->widAdvancedSettingLogo->style()->unpolish(ui->widAdvancedSettingLogo);
            ui->widAdvancedSettingLogo->style()->polish(ui->widAdvancedSettingLogo);

            ui->lblAdvancedSettingText->style()->unpolish(ui->lblAdvancedSettingText);
            ui->lblAdvancedSettingText->style()->polish(ui->lblAdvancedSettingText);
        }
        else if(o == ui->widBaseSetting)
        {
            ui->widBaseSetting->setProperty("selffocus","0");
            ui->widBaseSetting->style()->unpolish(ui->widBaseSetting);
            ui->widBaseSetting->style()->polish(ui->widBaseSetting);

            ui->widBaseSettingLogo->setProperty("selffocus","0");
            ui->lblBaseSettingText->setProperty("selffocus","0");

            ui->widBaseSettingLogo->style()->unpolish(ui->widBaseSettingLogo);
            ui->widBaseSettingLogo->style()->polish(ui->widBaseSettingLogo);

            ui->lblBaseSettingText->style()->unpolish(ui->lblBaseSettingText);
            ui->lblBaseSettingText->style()->polish(ui->lblBaseSettingText);
        }else if (o == ui->lineedit_widget)
        {
            ui->lineedit_widget->setProperty("selffocus","0");
            ui->lineedit_widget->style()->unpolish(ui->lineedit_widget);
            ui->lineedit_widget->style()->polish(ui->lineedit_widget);
        }else if (o == ui->leConfNumber)
        {
            ui->lineedit_widget->setProperty("selffocus","0");
            ui->lineedit_widget->style()->unpolish(ui->lineedit_widget);
            ui->lineedit_widget->style()->polish(ui->lineedit_widget);
            ui->lineedit_widget->update();
            ui->leConfNumber->setCursorPosition(ui->leConfNumber->text().count());
        }
    } else if (e->type() == QEvent::KeyRelease)
    {
        QKeyEvent *ke = dynamic_cast<QKeyEvent*>(e);

        if (ke && (ke->key() == Qt::Key_Right
                   || ke->key() == Qt::Key_Down
                   || ke->key() == Qt::Key_Left
                   || ke->key() == Qt::Key_Up))
        {
            if (QString(o->metaObject()->className()) == QString("ScheduleItem"))
            {
                o = ui->widgetScroll;
            }

            if (!m_ctrlOrder.contains(o))
            {
                return false;
            }
            QObject *target = m_ctrlOrder.value(o).at(OSDUtilsModel::instance().keyIndex(ke->key()));
            if (target)
            {
                if (target == ui->widgetScroll)
                {
                    if (!currentItem)
                    {
                        if(m_contentWidget && m_contentWidget->layout()->count() > 0)
                        {
                            currentItem = m_contentWidget->layout()->itemAt(0)->widget();
                        }
                    }
                    //item设置focus
                    QWidget* w = qobject_cast<QWidget*>(currentItem);
                    if (w) w->setFocus();
                }
                else if (target == POINTER_FOCUS_PREV)
                {
                    QWidget* w = qobject_cast<QWidget*>(currentItem);
                    if (w && m_contentWidget->layout()->indexOf(w) > 0)
                    {
                        focusPreviousChild();
                    }
                    else {
                        ui->lineedit_widget->setFocus();
                        ui->lineedit_widget->setProperty("selffocus","1");
                        ui->lineedit_widget->style()->unpolish(ui->lineedit_widget);
                        ui->lineedit_widget->style()->polish(ui->lineedit_widget);
                    }
                }
                else if (target == POINTER_FOCUS_NEXT)
                {
                    QWidget* w = qobject_cast<QWidget*>(currentItem);
                    if (w && (m_contentWidget->layout()->indexOf(w) < (m_contentWidget->layout()->count()-1)))
                        focusNextChild();
                }
                else{
                    dynamic_cast<QWidget*>(target)->setFocus();
                }
                return true;
            }
        }if (ke && (ke->key() == Qt::Key_Enter))
        {
            if (o == ui->leConfNumber)
            {
                ui->widCall->setFocus();
                return true;
            }
        }

    }else if (e->type() == QEvent::KeyPress)
    {
        if (o == ui->leConfNumber)
        {
            return false;
        }
        return true;
    }

    return false;
}

void IndexPage::refreshSchedule(LIST_SCHEDULES list)
{
    if (m_contentWidget)
    {
        QObjectList olist = m_contentWidget->children();
        foreach (QObject * oj, olist)
        {
            qDebug() << "obj:" << oj;
            if (dynamic_cast<QWidget *>(oj))
            {
                dynamic_cast<QWidget *>(oj)->close();
            }
        }
        delete m_contentWidget; m_contentWidget = NULL;
    }

    m_currentCount = list.count();

    if (m_currentCount == 0)
    {
        ui->swSch->setCurrentIndex(NO_SCHEDULE_PAGE);
        if (this->isVisible())
        {
            if (!ui->widBaseSetting->hasFocus() &&
                !ui->widAdvancedSetting->hasFocus() &&
                !ui->widCall->hasFocus() &&
                !ui->leConfNumber->hasFocus())
            {
                ui->lineedit_widget->setFocus();
            }
        }
        return;
    }
    ui->swSch->setCurrentIndex(SCHEDULE_PAGE);

    m_contentWidget = new QWidget(ui->widgetScroll);
    QVBoxLayout *pLayout = new QVBoxLayout();
    pLayout->setMargin(0);
    pLayout->setSpacing(20);
    std::sort(list.begin(), list.end(),compareAsc);


    for(int i = 0; i < list.count(); i++)
    {
        ScheduleItem *item = new ScheduleItem(m_contentWidget);
        item->installEventFilter(this);
        item->setData(list.at(i));
        pLayout->addWidget(item);
    }

    m_contentWidget->setLayout(pLayout);
    pLayout->setParent(m_contentWidget);
    m_contentWidget->adjustSize();
    m_originalHeight = m_contentWidget->height();   //为了还原原来的高度
    m_contentWidget->setGeometry(0,0,ui->widgetScroll->width(), m_contentWidget->height());
    m_contentWidget->show();
    if(m_contentWidget->layout()->count() > 0)
    {
        if (this->isVisible())
        {
            qDebug() << "shedule is visible";
            QWidget *w = m_contentWidget->layout()->itemAt(0)->widget();
            if (w) w->setFocus();
        }
    }
}

void IndexPage::showEvent(QShowEvent *e)
{
    QWidget::showEvent(e);
    if (!ui->widBaseSetting->hasFocus() &&
        !ui->widAdvancedSetting->hasFocus() &&
        !ui->widCall->hasFocus() &&
        !ui->leConfNumber->hasFocus())
    {
        ui->lineedit_widget->setFocus();
    }
}

void IndexPage::call(QString number,QString name)
{
    if (number.isEmpty())
    {
        QString str = "请输入会议号";
        MsgPageController::instance().showMsg(str);
        return;
    }
    //呼叫成功，跳转到呼叫控制
    //呼叫需密码，跳转到密码输入界面，把号码和名称带过去
    //呼叫失败，弹出提示框
    OSDRemoteServiceModel::instance().call(number,"",name);
}

void IndexPage::callSlot(BaseResp rv)
{
    qDebug() << "callSlot:";
    if (!this->isActiveWindow())
    {
        return;
    }
    if (rv.getCode() == RETURN_CODE_SUCCESS) {
        //跳转到呼叫控制界面
        MainWindowController::instance().changeSubPage(OSD::ViewGlobal::SUB_PAGE_MEET_LOADING);
    } else if (rv.getCode() == RETURN_CODE_NEED_PWD) {
        //跳转到密码提示页面
        PwdPageController::instance().inputPwd(m_confNum, SysConfigHandler::instance().deviceName());
    } else {
        //跳转到提示页面
        QString str = rv.getCodeString();
        MsgPageController::instance().showMsg(str);
    }
}

void IndexPage::loadSchedule()
{
    emit updateSchedule();
}


void IndexPage::timerHandle()
{
    QLocale locale = QLocale::Chinese;
    ui->lblCurrentTime->setText(QDateTime::currentDateTime().toString("HH:mm"));
    ui->lblCurrentDate->setText(QString(locale.toString(QDateTime::currentDateTime(), QString("MM-dd dddd"))));
}
